import pandas as pd
import os
from datetime import timedelta


def convert_daily_to_weekly(input_path, output_path):
    # 读取日线数据（增加详细错误处理）
    try:
        # 尝试多种编码方式读取
        for encoding in ['gbk', 'utf-8-sig', 'latin1']:
            try:
                df = pd.read_csv(input_path, encoding=encoding)
                print(f"成功使用 {encoding} 编码读取文件")
                break
            except UnicodeDecodeError:
                print(f"使用 {encoding} 编码读取失败")
        else:
            # 如果所有编码尝试都失败
            df = pd.read_csv(input_path, encoding='gbk', errors='replace')
            print("使用替换模式读取文件")

    except Exception as e:
        print(f"读取文件时发生错误: {str(e)}")
        return None

    # 显示原始数据前5行用于调试
    print("\n原始数据前5行:")
    print(df.head())

    # 验证必要字段是否存在
    required_columns = ['股票代码', '交易日期', '后复权开盘价', '后复权收盘价',
                        '后复权最高价', '后复权最低价', '成交量', '成交额']

    missing_cols = [col for col in required_columns if col not in df.columns]
    if missing_cols:
        raise ValueError(f"缺少必要字段: {missing_cols}")

    # 强制转换日期格式（关键修复）
    def parse_date(date_str):
        """强制转换为YYYYMMDD格式的日期"""
        try:
            # 统一转换为字符串处理
            date_str = str(date_str).strip()

            # 处理数字格式（如20230101）
            if date_str.isdigit() and len(date_str) == 8:
                return pd.to_datetime(date_str, format='%Y%m%d')

            # 处理常见日期格式
            return pd.to_datetime(date_str)
        except:
            return pd.NaT

    df['交易日期'] = df['交易日期'].apply(parse_date)

    # 排除无效日期
    invalid_dates = df[df['交易日期'].isna()]
    if not invalid_dates.empty:
        print(f"\n发现 {len(invalid_dates)} 条无效日期记录，已排除")
        df = df[df['交易日期'].notna()]

    # 检查是否仍有有效数据
    if df.empty:
        raise ValueError("所有日期解析失败，请检查日期格式是否为YYYYMMDD")

    # 按日期排序
    df = df.sort_values('交易日期').reset_index(drop=True)

    # 显示转换后的日期用于调试
    print("\n转换后的日期范围:")
    print(f"最早日期: {df['交易日期'].min()}, 最晚日期: {df['交易日期'].max()}")

    # 初始化结果列表
    weekly_data = []

    # 初始化当前周的数据组
    current_group = []

    for i, row in df.iterrows():
        if not current_group:  # 新建一组
            current_group.append(row)
        else:
            prev_date = current_group[-1]['交易日期']
            curr_date = row['交易日期']

            # 调试输出
            # print(f"\n处理日期: {prev_date} -> {curr_date}")

            # 判断是否为连续交易日
            if (curr_date - prev_date).days == 1:  # 连续日期
                current_group.append(row)
            else:
                # 判断前一个日期是否为周五
                if prev_date.weekday() == 4:  # 周五
                    # 结束当前组
                    weekly_data.append(process_group(current_group))
                    current_group = [row]
                else:
                    # 判断是否属于同一周
                    prev_week = prev_date.isocalendar().week
                    curr_week = curr_date.isocalendar().week

                    # 如果跨周了，结束当前组
                    if prev_week != curr_week:
                        weekly_data.append(process_group(current_group))
                        current_group = [row]
                    else:
                        # 继续加入当前组直到遇到非连续日期
                        current_group.append(row)

    # 处理最后一组数据
    if current_group:
        weekly_data.append(process_group(current_group))

    # 创建DataFrame并保存
    if not weekly_data:
        raise ValueError("未生成任何周线数据，请检查原始数据")

    weekly_df = pd.DataFrame(weekly_data)
    weekly_df = weekly_df[['股票代码', '交易开始日期', '交易结束日期',
                           '周线_后复权开盘价', '周线_后复权最高价',
                           '周线_后复权最低价', '周线_后复权收盘价',
                           '周线_成交量', '周线_成交额']]

    # 确保输出目录存在
    os.makedirs(os.path.dirname(output_path), exist_ok=True)

    # 保存结果（使用UTF-8-BOM格式，确保Excel能正确识别中文）
    weekly_df.to_csv(output_path, index=False, encoding='utf-8-sig')

    print(f"\n成功生成周线数据 {len(weekly_df)} 条")
    print("\n生成的周线数据示例:")
    print(weekly_df.head())

    return weekly_df


def process_group(group):
    """处理一组连续交易日的数据"""
    first_row = group[0]
    last_row = group[-1]

    # 计算各项指标
    week_data = {
        '股票代码': first_row['股票代码'],
        '交易开始日期': first_row['交易日期'],
        '交易结束日期': last_row['交易日期'],
        '周线_后复权开盘价': first_row['后复权开盘价'],
        '周线_后复权收盘价': last_row['后复权收盘价'],
        '周线_后复权最高价': max(row['后复权最高价'] for row in group),
        '周线_后复权最低价': min(row['后复权最低价'] for row in group),
        '周线_成交量': sum(row['成交量'] for row in group),
        '周线_成交额': sum(row['成交额'] for row in group)
    }

    # 调试输出
    # print(f"\n处理周数据: {week_data['交易开始日期']} - {week_data['交易结束日期']}")

    return week_data


# 使用示例
if __name__ == "__main__":
    input_file = r"D:\pythonProject\BaiduSyncdisk\LongMoneyTrade\各部分数据\后复权日线\个股_后复权日线\000001.sz.csv"
    output_file = r"D:\pythonProject\BaiduSyncdisk\LongMoneyTrade\各部分数据\后复权周线\周线000001.sz.csv"  # 修改后的文件名

    try:
        result = convert_daily_to_weekly(input_file, output_file)
        print("程序执行完成")
    except Exception as e:
        print(f"程序执行过程中发生错误: {str(e)}")
